# -*- coding: utf-8 -*-
"""
Created on Sun May 14 12:23:39 2017

@author: GangTimes
"""

import numpy
import primal
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm


#绘图设置
zh_font=fm.FontProperties(fname=r"c:\windows\fonts\simsun.ttf",size=18)#路径用小写  大写不行 有这个不能保存为eps
en_font=fm.FontProperties(family='monospace',size=18)
zf_font=fm.FontProperties(family='Times New Roman',style='italic',size=16)

fig_model=plt.figure(figsize=(7,5))
ax_model=fig_model.add_axes([0.14,0.14,0.85,0.85])
#a3x=Axes3D(fig,[0.,0.0,1,1])
plt.rcParams['axes.unicode_minus']=False #用来正常显示负

#全局参数
num=80
version='1.0'

def self_plot(x,y,z):
    x1=[]
    x2=[]
    y1=[]
    y2=[]

    for index in range(num):
        if z[index,0]==-1:
            x1.append(x[index,0])
            y1.append(y[index,0])
        else:
            x2.append(x[index,0])
            y2.append(y[index,0])
    
    ax_model.plot(x1,y1,"*r")
    ax_model.plot(x2,y2,"ok")

    
def create_data(theta):
    '''
    用于生成一个二维空间的两种类型的点
    人为制造一定的误差
    return:matrix[nx3] n为样本数量  [x y z]三列
    '''
    x=numpy.matrix(numpy.random.uniform(0,1,num)).T
    y=numpy.matrix(numpy.random.uniform(0,1,num)).T  
    
    x_one=numpy.matrix(numpy.ones((num,1)))
    
    z=model_fun(theta,numpy.hstack((x,y,x_one)))
    self_plot(x,y,z)
    
    return numpy.hstack((x,y,z))            
            
def model_fun(theta,x):
    '''
    这是模型函数
    theta:系数 matrix[mx1]  m为变量数
    x:自变量 matrix[nxm]  n为样本数   m为变量数 其中第一列对应的是 1 
    return: matrix[nx1]
    '''
    temp=(theta.T * x.T).T
    rows=temp.shape[0]
    yval=[]
    if rows==1:
        yval.append(_sign_fun(temp[0,0],0))
        return numpy.matrix(yval)
    elif rows>1:
        for index in range(rows):
            yval.append(_sign_fun(temp[index,0],0))
        return numpy.matrix(yval).T
            

def _sign_fun(x,b):
    '''
    sign函数  符号判别函数
    x:自变量 
    b:参考变量
    '''
    if x>=b:
        return 1
    else:
        return -1

def residul_plot(loss):
    '''
    绘制残差曲线
    '''
    rs_fig=plt.figure(figsize=(7,5))
    ax=rs_fig.add_axes([0.14,0.14,0.85,0.85])
    ax.plot(loss,'-r')
    plt.show()

def model_plot(theta):
    '''
    绘制模型函数的图像
    theta: matrix[mx1]
    ax+by+c=0
    '''
    a=theta[0,0]
    b=theta[1,0]
    c=theta[2,0]
    
    x=numpy.linspace(0,1,100)
    y=(-a/b)*x+(-c/b)    
    ax_model.plot(x,y,'-r')
    plt.show()
 

def primal_demo():
    '''
    PLA primal 算法程序
    '''
    rtheta=numpy.matrix([[1],[1],[-1]])
    temp=create_data(rtheta)
    
    x_one=numpy.matrix(numpy.ones((num,1)))
    x=numpy.hstack((temp[:,0:2],x_one))
    y=temp[:,2]
    
    [theta,loss]=primal.primal(x,y)
    
    model_plot(theta)
    residul_plot(loss)


if __name__=="__main__":
    primal_demo()
